package com.tuanzi.loan.business.repository.system.impl;

import static com.tuanzi.loan.generated.jooq.loan.tables.LoanDataPermissionRelation.LOAN_DATA_PERMISSION_RELATION;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanFunctionalPermissionRelation.LOAN_FUNCTIONAL_PERMISSION_RELATION;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanRole.LOAN_ROLE;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanSystemUser.LOAN_SYSTEM_USER;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanUserRole.LOAN_USER_ROLE;

import java.util.List;

import org.jooq.Record;
import org.jooq.RecordMapper;
import org.jooq.impl.TableImpl;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import com.tuanzi.loan.business.entity.system.Role;
import com.tuanzi.loan.business.repository.system.custom.RoleRepositoryCustom;
import com.tuanzi.loan.core.repository.JOOQBaseRepository;
import com.tuanzi.loan.vo.request.system.RoleSearchRequest;
import com.tuanzi.loan.vo.response.system.RoleSearchResponse;

/**
 * @author Ray 2017/09/21
 */
@Repository
@SuppressWarnings({ "rawtypes" })
public class RoleRepositoryImpl extends JOOQBaseRepository implements RoleRepositoryCustom {

	@Override
	protected TableImpl getTable() {
		return LOAN_ROLE;
	}

	@Override
	public Page<RoleSearchResponse> list(RoleSearchRequest searchRequest, Pageable pageable) {

		fields(LOAN_ROLE.ID, LOAN_ROLE.CODE, LOAN_ROLE.NAME, LOAN_ROLE.ENABLE, LOAN_FUNCTIONAL_PERMISSION_RELATION.ID, LOAN_DATA_PERMISSION_RELATION.ID, LOAN_USER_ROLE.ID);

		leftJoin(LOAN_FUNCTIONAL_PERMISSION_RELATION, LOAN_ROLE.ID.eq(LOAN_FUNCTIONAL_PERMISSION_RELATION.RELATION_ID)
				.and(LOAN_FUNCTIONAL_PERMISSION_RELATION.PERMISSION_ID.eq(searchRequest.getFunctionalPermissionId())));

		leftJoin(LOAN_DATA_PERMISSION_RELATION,
				LOAN_ROLE.ID.eq(LOAN_DATA_PERMISSION_RELATION.RELATION_ID).and(LOAN_DATA_PERMISSION_RELATION.PERMISSION_ID.eq(searchRequest.getDataPermissionId())));

		leftJoin(LOAN_USER_ROLE, LOAN_ROLE.ID.eq(LOAN_USER_ROLE.ROLE_ID).and(LOAN_USER_ROLE.USER_ID.eq(searchRequest.getUserId())));

		contains(LOAN_ROLE.CODE, searchRequest.getCode());
		contains(LOAN_ROLE.NAME, searchRequest.getName());
		eq(LOAN_ROLE.ENABLE, searchRequest.getEnable());
		return search(pageable, new RoleSearchResponseRecordMapper());
	}

	@Override
	public List<Role> findAllByAccount(String account) {
		fields(LOAN_ROLE.fields());
		innerJoin(LOAN_USER_ROLE, LOAN_ROLE.ID.eq(LOAN_USER_ROLE.ROLE_ID));
		innerJoin(LOAN_SYSTEM_USER, LOAN_SYSTEM_USER.ID.eq(LOAN_USER_ROLE.USER_ID));
		eq(LOAN_SYSTEM_USER.ACCOUNT, account);
		return search(Role.class);
	}

	@Override
	public List<Role> findAllByUserId(String userId) {
		fields(LOAN_ROLE.fields());

		leftJoin(LOAN_USER_ROLE, LOAN_ROLE.ID.eq(LOAN_USER_ROLE.ROLE_ID).and(LOAN_USER_ROLE.USER_ID.eq(userId)));

		return search(Role.class);
	}

	@Override
	public Long countByAccountAndRoleCode(String account, String roleCode) {
		innerJoin(LOAN_USER_ROLE, LOAN_ROLE.ID.eq(LOAN_USER_ROLE.ROLE_ID));
		innerJoin(LOAN_SYSTEM_USER, LOAN_SYSTEM_USER.ID.eq(LOAN_USER_ROLE.USER_ID));
		eq(LOAN_ROLE.CODE, roleCode);
		eq(LOAN_SYSTEM_USER.ACCOUNT, account);
		return count();
	}

	private final class RoleSearchResponseRecordMapper implements RecordMapper<Record, RoleSearchResponse> {

		@Override
		public RoleSearchResponse map(Record record) {
			RoleSearchResponse response = new RoleSearchResponse();
			response.setId(record.get(LOAN_ROLE.ID));
			response.setCode(record.get(LOAN_ROLE.CODE));
			response.setName(record.get(LOAN_ROLE.NAME));
			response.setEnable(record.get(LOAN_ROLE.ENABLE));
			response.setRelatedFunctionalPermission(record.get(LOAN_FUNCTIONAL_PERMISSION_RELATION.ID) != null);
			response.setRelatedDataPermission(record.get(LOAN_DATA_PERMISSION_RELATION.ID) != null);
			response.setRelatedUser(record.get(LOAN_USER_ROLE.ID) != null);
			return response;
		}
	}

}
